package net.guerlab.smart.wx.service.service.impl;

import net.guerlab.smart.wx.auth.utils.WxUserJwtHelper;
import net.guerlab.smart.wx.core.domain.LoginResponse;
import net.guerlab.smart.wx.core.domain.WxUserDTO;
import net.guerlab.smart.wx.core.exception.WxAppInvalidException;
import net.guerlab.smart.wx.service.entity.WxApp;
import net.guerlab.smart.wx.service.entity.WxUser;
import net.guerlab.smart.wx.service.service.LoginService;
import net.guerlab.smart.wx.service.service.WxAppService;
import net.guerlab.smart.wx.service.service.WxUserLoginLogService;
import net.guerlab.smart.wx.service.service.WxUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * 抽象微信登录服务实现
 *
 * @author guer
 */
@Transactional(rollbackFor = Exception.class)
public abstract class AbstractWxLoginServiceImpl implements LoginService {

    protected WxUserJwtHelper jwtHelper;

    protected WxUserService wxUserService;

    protected WxAppService wxAppService;

    protected WxUserLoginLogService wxUserLoginLogService;

    protected void updateUserInfo(WxUser wxUser, String openId, String unionId, boolean updateActivated, String ip,
            String referer) {
        LocalDateTime now = LocalDateTime.now();

        WxUser update = new WxUser();
        update.setOpenId(openId);
        update.setAppId(wxUser.getAppId());
        update.setUnionId(unionId);
        update.setLastLoginTime(now);
        update.setVersion(wxUser.getVersion());

        if (wxUser.getRegistryTime() == null) {
            update.setRegistryTime(now);
        }
        if (updateActivated) {
            update.setActivated(wxUser.getActivated());
        }

        wxUserService.updateSelectiveById(update);

        wxUser.setUnionId(unionId);
        wxUser.setLastLoginTime(update.getLastLoginTime());
        if (wxUser.getRegistryTime() == null) {
            update.setRegistryTime(now);
        }

        wxUserLoginLogService.addLog(wxUser, ip, referer);
    }

    @Override
    public LoginResponse buildLoginResponse(WxUser user) {
        WxUserDTO dto = user.toDTO();

        LoginResponse loginSucceedDTO = new LoginResponse();
        loginSucceedDTO.setInfo(dto);
        loginSucceedDTO.setAccessToken(jwtHelper.generateByAccessToken(user));
        loginSucceedDTO.setRefreshToken(jwtHelper.generateByRefreshToken(user));

        return loginSucceedDTO;
    }

    protected WxApp getWxApp(String appId) {
        WxApp wxApp = wxAppService.selectById(appId);

        if (wxApp == null || !wxApp.getEnable()) {
            throw new WxAppInvalidException();
        }

        return wxApp;
    }

    @Autowired
    public void setJwtHelper(WxUserJwtHelper jwtHelper) {
        this.jwtHelper = jwtHelper;
    }

    @Autowired
    public void setWxUserService(WxUserService wxUserService) {
        this.wxUserService = wxUserService;
    }

    @Autowired
    public void setWxAppService(WxAppService wxAppService) {
        this.wxAppService = wxAppService;
    }

    @Autowired
    public void setWxUserLoginLogService(WxUserLoginLogService wxUserLoginLogService) {
        this.wxUserLoginLogService = wxUserLoginLogService;
    }
}
